from .window_manager import WindowManager
from typing import Tuple, Optional
import win32gui
import win32ui
import win32con
import numpy as np
from PIL import Image
from utils.async_manager import AsyncManager
from utils.ocr.ocr_manager import GlobalOcr
import cv2

class WindowPyAuto:
    def __init__(self, hwnd: None):
        self.hwnd = hwnd
        self.window_manager = WindowManager(hwnd)
        self.ocr = GlobalOcr()
        self.init()
        
    def init(self):
        # 获取窗口DC
        self.hwnd_dc = win32gui.GetWindowDC(self.hwnd)
        self.mfc_dc = win32ui.CreateDCFromHandle(self.hwnd_dc)
    
    
    def set_offset_window(self, region: Tuple[int, int, int, int]) -> Tuple[int, int]:
        """
        计算窗口偏移量
        Args:
            region: (left, top, right, bottom) 相对于窗口的坐标
        Returns:
            (offset_x, offset_y): 相对于屏幕的实际坐标偏移量
        """
        window_info = self.window_manager.find_window(self.hwnd).to_dict()
        # 获取窗口在屏幕上的位置
        window_x, window_y, _, _ = window_info['position']
        
        # 计算实际的屏幕坐标
        screen_x = window_x + region[0]  # 左上角x
        screen_y = window_y + region[1]  # 左上角y
        
        return screen_x, screen_y
    
    
        
    # 获取游戏地图
    def get_game_map_title(self, region: Tuple[int, int, int, int]) -> Image.Image:
        """
        获取游戏标题截图，即使窗口被覆盖也能截图
        Args:
            region: (left, top, right, bottom) 相对于窗口的坐标
        Returns:
            PIL.Image: 截图对象
        """
        try:
            
            save_dc = self.mfc_dc.CreateCompatibleDC()
            
            # 计算截图区域的宽度和高度
            width = region[2] - region[0]   # right - left
            height = region[3] - region[1]  # bottom - top
            
            # 创建位图对象
            save_bitmap = win32ui.CreateBitmap()
            save_bitmap.CreateCompatibleBitmap(self. mfc_dc, width, height)
            save_dc.SelectObject(save_bitmap)
            
            # 复制窗口内容到位图
            save_dc.BitBlt(
                (0, 0), 
                (width, height), 
                self.mfc_dc, 
                (region[0], region[1]), 
                win32con.SRCCOPY
            )
            
            # 将位图转换为PIL Image
            bmpinfo = save_bitmap.GetInfo()
            bmpstr = save_bitmap.GetBitmapBits(True)
            image = Image.frombuffer(
                'RGB',
                (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
                bmpstr, 'raw', 'BGRX', 0, 1
            )
            
            # 清理资源
            win32gui.DeleteObject(save_bitmap.GetHandle())
            save_dc.DeleteDC()
            self.mfc_dc.DeleteDC()
            win32gui.ReleaseDC(self.hwnd, self.hwnd_dc)
            
            return image
            
        except Exception as e:
            print(f"截图失败: {str(e)}")
            return None
    
    def get_window_screenshot(self) -> Image.Image:
        """
        获取整个窗口的截图
        Returns:
            PIL.Image: 窗口截图
        """
        try:
            # 获取窗口尺寸
            left, top, right, bottom = win32gui.GetWindowRect(self.hwnd)
            width = right - left
            height = bottom - top
            
            # 获取口DC
            hwnd_dc = win32gui.GetWindowDC(self.hwnd)
            mfc_dc = win32ui.CreateDCFromHandle(hwnd_dc)
            save_dc = mfc_dc.CreateCompatibleDC()
            
            # 创建位图对象
            save_bitmap = win32ui.CreateBitmap()
            save_bitmap.CreateCompatibleBitmap(mfc_dc, width, height)
            save_dc.SelectObject(save_bitmap)
            
            # 复制窗口内容到位图
            save_dc.BitBlt(
                (0, 0), 
                (width, height), 
                mfc_dc, 
                (0, 0), 
                win32con.SRCCOPY
            )
            
            # 将位图转换为PIL Image
            bmpinfo = save_bitmap.GetInfo()
            bmpstr = save_bitmap.GetBitmapBits(True)
            image = Image.frombuffer(
                'RGB',
                (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
                bmpstr, 'raw', 'BGRX', 0, 1
            )
            
            # 清理资源
            win32gui.DeleteObject(save_bitmap.GetHandle())
            save_dc.DeleteDC()
            mfc_dc.DeleteDC()
            win32gui.ReleaseDC(self.hwnd, hwnd_dc)
            
            return image
            
        except Exception as e:
            print(f"窗截图失败: {str(e)}")
            return None
    
    # 获取角色信息
    def get_roles_info(self):
        try:
            # 获取窗口尺寸
            def get_hp():
                # 获取血量
                hp_region = (133, 77, 203, 90)  # left, top, right, bottom
                # 创建兼容DC
                save_dc = self.mfc_dc.CreateCompatibleDC()
                # 计算截图区域的宽度和高度
                width = hp_region[2] - hp_region[0]   # 70 pixels
                height = hp_region[3] - hp_region[1]  # 13 pixels
                # 创建位图对象
                save_bitmap = win32ui.CreateBitmap()
                save_bitmap.CreateCompatibleBitmap(self.mfc_dc, width, height)
                save_dc.SelectObject(save_bitmap)
                
                # 复制窗口内容到位图
                save_dc.BitBlt(
                    (0, 0),
                    (width, height),
                    self.mfc_dc,
                    (hp_region[0], hp_region[1]),
                    win32con.SRCCOPY
                )
                
                # 将位图转换为PIL Image
                bmpinfo = save_bitmap.GetInfo()
                bmpstr = save_bitmap.GetBitmapBits(True)
                image = Image.frombuffer(
                    'RGB',
                    (bmpinfo['bmWidth'], bmpinfo['bmHeight']),
                    bmpstr, 'raw', 'BGRX', 0, 1
                )
                
                # 清理资源
                win32gui.DeleteObject(save_bitmap.GetHandle())
                save_dc.DeleteDC()
                return image
            
            hp = "100%"
            mp = 0
            
            
            # 开启异步处理
            asyncio.run(get_hp())
          
            
            # 获取魔法值
            def get_mp():
                # 获取魔法值
                pass
            
            return { hp,mp}
        except Exception as e:
            print(f"获取角色信息失败: {str(e)}")
            return None
    
    def _init_dc(self):
        """初始化设备上下文"""
        try:
            self.hwnd_dc = win32gui.GetWindowDC(self.hwnd)
            self.mfc_dc = win32ui.CreateDCFromHandle(self.hwnd_dc)
        except Exception as e:
            print(f"初始化DC失败: {e}")
            self._release_dc()
            
    def _release_dc(self):
        """释放设备上下文"""
        try:
            if self.mfc_dc:
                self.mfc_dc.DeleteDC()
                self.mfc_dc = None
            if self.hwnd_dc:
                win32gui.ReleaseDC(self.hwnd, self.hwnd_dc)
                self.hwnd_dc = None
        except Exception as e:
            print(f"释放DC失败: {e}")
            
    def get_hp_screenshot(self) -> Optional[np.ndarray]:
        """获取血量区域的截图"""
        try:
            # 血量数字的区域
            hp_region = (133, 77, 203, 90)  # left, top, right, bottom
            
            # 使用GlobalOcr的window_capture方法
            img = self.ocr.window_capture(
                self.hwnd,
                start_point=(hp_region[0], hp_region[1]),
                size=(hp_region[2]-hp_region[0], hp_region[3]-hp_region[1]),
                debug=True
            )
            
            return img
            
        except Exception as e:
            print(f"获取HP区域截图失败: {e}")
            return None